#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>


//void test()
//{
//	printf("test\n");
//}
//
//
//int main()
//{
//	int i = 0;
//	for (i = 0; i < 10; i++)
//	{
//		printf("hehe\n");
//	}
//	for (i = 0; i < 10; i++)
//	{
//		printf("haha\n");
//		test();
//	}
//	return 0;
//}

//调试举例1
//求1-3的阶乘的和

//求一个数的阶乘

//int main()
//{
//	int n = 0;
//	scanf("%d", &n);
//	int i = 0;
//	int ret = 1;
//	for (i = 1; i <= n; i++)
//	
//		ret *= i;
//	}
//	printf("%d", ret);
//
//	return 0;
//}

//求连续的数的阶乘的和

//int main()
//{
//	int n = 0;
//	int i = 0;
//	int ret = 1;
//	int sum = 0;
//	for (n = 1; n <= 3; n++)
//	{
//		
//
//		for (i = 1; i <= n; i++)
//		{
//			ret *= i;
//		}
//		sum += ret;
//	}
//	printf("%d\n", sum);
//
//	return 0;
//}
//调试这段代码，发现在算1和2的阶乘，并且相加都没有错，在算3的阶乘就出现，发现是ret定义在了for外面
//导致每一次进行相加的时候，ret都累加了上次的结果

//修改
//int main()
//{
//	int n = 0;
//	int i = 0;
//	int ret = 1;
//	int sum = 0;
//	for (n = 1; n <= 3; n++)
//	{
//		ret = 1;
//
//		for (i = 1; i <= n; i++)
//		{
//			ret *= i;
//		}
//		sum += ret;
//	}
//	printf("%d\n", sum);
//
//	return 0;
//}

//算法优化
//int main()
//{
//	int n = 0;
//	int ret = 1;
//	int sum = 0;
//	for (n = 1; n <= 3; n++)
//	{
//		ret *= n;                    //1! = 1 * 1 
//		sum += ret;                  //2！= 1 * 1 * 2
//	}                                //3! = 1 * 1 * 2 * 3
//	printf("%d\n", sum);
//
//	return 0;
//}

#include <stdio.h>

int main()//0x00AFF8A4
{
	int i = 0;

	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	for (i = 0; i <= 12; i++)
	{
		arr[i] = 0;
		printf("hehe\n");
	}
	return 0;
}
//按理讲，应该是数组越界，应该是报错，程序崩溃，但实际运行起来
//结果是死循环，为什么呢？调试一下

//调试结果发现，数组的确越界了，将arr[11]和arr[10]也赋为0，
// 然后到arr[12]的时候，赋值为0的时候，i的值居然也变成了0
// 猜想，储存i的内存和储存arr[12]的内存空间应该是一样的，所以
// 将0赋给arr[12]的时候，把i也给赋值为0的
// 可以打开调试的内存窗口，&i和&arr[12]验证
// 的确如猜想一样两个的地址都是0x00AFF8A4

//那为什么会死循环而不是报错呢？？？
//很简单，编译器忙着死循环而没机会报错..

//补充：
// 1.栈区内存的使用习惯是从高地址向低地址使用的，所以变量i的地址是比较大的。arr数组的地址整体是小于i的地址的
// 2.数组在内存中的存放是：随着下标的增长，地址是由低到高变化的。
// 3.为什么i和arr数组之间恰好空出2个整形的字节，这是一个巧合，所以此次距离极其依赖环境
// vs2022，x86，Debug
//
